/**
 * @createTime: 2019/1/29 0029
 * @author: HingLo
 * @description: ehcache 3.x 使用
 */

package cn.hinglo.ehcahe.plugin;

import org.ehcache.Cache;
import org.ehcache.CacheManager;

import java.util.concurrent.ConcurrentHashMap;


/**
 * CacheKit. Useful tool box for EhCache.
 */
public class CacheKit {


    private static CacheManager cacheManager;
    private final static ConcurrentHashMap<String, Cache> cacheMap = new ConcurrentHashMap<>();

    static void init(CacheManager cacheManager) {
        CacheKit.cacheManager = cacheManager;
    }

    public static CacheManager getCacheManager() {
        return cacheManager;
    }


    private static Cache getCache(String name) {
        return cacheMap.get(name);
    }

    /***
     *  添加缓存的时候获取缓存器,
     *  注意：如果在添加的时候没有获取到配置文件中的指定的缓存器，就直接抛出一个异常，开发过程中就必须指定缓存名称，避免出错
     * @param name 缓存的名称
     * @param key key类型
     * @param value  value类型
     * @param <K> 泛型
     * @param <V> 泛型
     * @return 返回指定类型的缓存器
     */
    private static <K, V> Cache putCache(String name, Class<K> key, Class<V> value) {
        Cache cache = getCache(name);
        if (cache == null) {
            cache = cacheManager.getCache(name, key, value);
            if (cache == null) {
                // 手动创建一个缓存器，key为String,value为：object
                throw new RuntimeException("没有获取到该缓存名称的缓存器，请检查配置文件中是或否配置了该缓存器");
            }
            cacheMap.put(name, cache);
        }
        return cache;

    }

    /***
     *  添加缓存
     * @param cacheName  缓存名称
     * @param key key
     * @param value value
     * @param <K> key 的泛型
     * @param <V> value 的泛型
     */
    public static <K, V> void put(String cacheName, K key, V value) {
        putCache(cacheName, key.getClass(), value.getClass()).put(key, value);
    }

    /***
     * 获取缓存信息的值
     * @param name 缓存的名称
     * @param key key
     * @param <K> 泛型key
     * @param <V> 接受的值
     * @return
     */
    public static <K, V> V get(String name, K key) {
        return (V) getCache(name).get(key);
    }


    /***
     *  删除指定name的可以
     * @param cacheName 缓存的名称
     * @param key key
     * @param <T> 泛型key
     */
    public static <T> void remove(String cacheName, T key) {
        Cache cache = getCache(cacheName);
        if (cache == null) {
            cache.remove(key);
        }
    }

    /***
     * 清理指定缓存名称下缓存的全部数据
     * @param cacheName 缓存的名称
     */
    public static void removeAll(String cacheName) {
        getCache(cacheName).clear();
    }


}


